<template>
  <form
    class="x-form form" 
    :class="['form-'+options.type]" 
    :novalidate="options.novalidate" 
    @submit.prevent="onSubmit">
    <x-group 
      v-for="s in schema" 
      :key="s.name" 
      :schema="s" 
      :validation="$v.model[s.name]"
    >
      <component 
        :is="'x-'+s.type" 
        :model.sync="model" 
        :schema="s" 
        :ref="_ref(s.name)" 
        :event="event">
      </component>
    </x-group>
  </form>
</template>
<script>
import {validationMixin} from 'vuelidate'
import * as validators from 'vuelidate/lib/validators'
import * as common from 'vuelidate/lib/validators/common'

import XGroup from './XGroup.vue'
import XStatic from './XStatic.vue'
import XInput from './XInput.vue'
import XTextarea from './XTextarea.vue'
import XSelect from './XSelect.vue'
import XCheckbox from './XCheckbox.vue'
import XButton from './XButton.vue'

validators.regex = function (regex) {
  return common.regex('regex', regex)
}

export default {
  name: 'XForm',
  mixins: [validationMixin],
  validators,
  common,
  components: {
    XGroup,
    XStatic,
    XInput,
    XTextarea,
    XSelect,
    XCheckbox,
    XButton
  },
  props: {
    schema: {
      type: Array,
      default () {
        return []
      }
    },
    model: {
      type: Object,
      default () {
        return {}
      }
    },
    options: {
      type: Object,
      default () {
        return {
          type: 'vertical'
        }
      }
    },
    event: {
      type: Function,
      default () {}
    }
  },
  methods: {
    registerComponent (Component) {
      this.$options.components[component.name] = Component
    },
    getField (name) {
      return this.$refs[name][0]
    },
    getValue() {
      return this.model
    },
    setValue (model) {
      Object.assign(this.model, model)
    },
    onSubmit () {
      this.$v.$touch()
      if (!this.$v.$error) {
        this.$emit('submit')
      }
    },
    _ref (name) {
      return name
    }
  },
  validations () {
    var validation = {}
    this.schema.forEach((item) => {
      validation[item.name] = {}
      if (item.required) {
        validation[item.name].required = validators.required
      }
      if (validators[item.inputType]) {
        validation[item.name][item.inputType] = validators[item.inputType]
      }
      if (item.pattern) {
        validation[item.name].regex = validators.regex(item.pattern)
      }
    })
    return {
      model: validation
    }
  }
}
</script>
<style></style>